package main

import (
	"fmt"
	mock2 "learngo/retriever/mock"
	real2 "learngo/retriever/real"
	"time"
)

type Retriever interface {
	// 接口声明
	Get(url string) string
}

type Poster interface {
	Post(url string, form map[string]string) string
}

const url = "http://www.imooc.com"

func download(r Retriever) string {
	return r.Get("https://www.baidu.com")
}

func post(poster Poster) {
	poster.Post("http://www.imooc.com", map[string]string{
		"name":   "abc",
		"course": "golang",
	})
}

type RetrieverPoster interface {
	Retriever
	Poster
}

func session(s RetrieverPoster) string {
	s.Post(url, map[string]string{
		"contents": "another faked imooc.com",
	})
	return s.Get(url)
}

func inspect(r Retriever) {
	// interface类型判断
	fmt.Println("Inspecting", r)
	fmt.Printf(" > %T %v\n", r, r) // %T 是类型，%v, %T是字节码，%c是rune字符
	fmt.Print(" > Type switch:")
	switch v := r.(type) {
	case *mock2.Retriever:
		fmt.Println("Contents:", v.Contents)
	case *real2.Retriever:
		fmt.Println("UserAgent:", v.UserAgent)
	}
	fmt.Println()
}

func main() {
	var r Retriever // 接口变量
	retriever := mock2.Retriever{"this is a fake imooc.com"}
	r = &retriever
	inspect(r) // 接口变量中有实现着的类型，实现者的指针
	// Type assertion
	if realRetriever, ok := r.(*real2.Retriever); ok {
		fmt.Println(realRetriever.TimeOut)
	} else {
		fmt.Println(" not a real retriever")
	}

	r = &real2.Retriever{
		UserAgent: "Mozilla/5.0",
		TimeOut:   time.Minute,
	}
	inspect(r)
	fmt.Println("try a session")
	fmt.Println(session(&retriever))

	// real.Retriever { 0s}
	//fmt.Println(download(r))
}
